#include "exception.hpp"
#include "texturelist.hpp"
#include <algorithm>

#include <iostream>

using namespace Shiny;
using namespace std;
using namespace sf;

/**********************/
/*    ANIMATIONLIST   */
/**********************/
AnimationList::AnimationList(Data data, TextureList& tex)
{
  Data                        list    = data["Animations"];
  Data::iterator              current = list.begin();
  Data::iterator              end     = list.end();

  if (list.Nil())
    return ;
  end = list.end();
  for (; current != end ; ++current)
  {
    Animation anim((*current).Key(), (*current), tex);

    _anims.push_back(anim);
  }
}

const AnimationList::Animation* AnimationList::operator[](const string& name) const
{
  vector<Animation>::const_iterator res = find(_anims.begin(), _anims.end(), name);

  return ((res == _anims.end()) ? 0 : &(*res));
}

const std::string fieldsAnim[] = { "Texture", "Frames", "Refresh", "Looping", "Rect" };
const std::string fieldsRect[] = { "OffsetX", "OffsetY", "SizeX", "SizeY" };

AnimationList::Animation::Animation(const string& name, Data data, TextureList& tex) : _name(name)
{
  Data      fields[5];
  
  for (unsigned int i = 0 ; i < 5 ; ++i)
  {
    fields[i] = data[fieldsAnim[i]];
    if (fields[i].Nil())
    {
      cout << "Field missing: " << fieldsAnim[i] << endl;
      throw 1; // Error : field missing : fieldAnim[i]
    }
  }
  _tex         = tex[fields[0].Value()];
  if (_tex == 0)
  {
    cout << "[Animation] Texture " << fields[0].Value() << " does not exist" << endl;
    throw 1;
  }
  _nFrames     = fields[1];
  _refreshRate = fields[2];
  _inLoop      = ((fields[3].Value() == "1") ? true : false);
  LoadRect(fields[4]);
}

void AnimationList::Animation::LoadRect(Data data)
{
  Data  fields[4];

  for (unsigned int i = 0 ; i < 4 ; ++i)
  {
    fields[i] = data[fieldsRect[i]];
    if (fields[i].Nil())
    {
      cout << "Field missing: " << fieldsRect[i] << endl;
      throw 1; // Error: field missing: fieldsRect[i]
    }
  }
  _rect.Left   = fields[0];
  _rect.Top    = fields[1];
  _rect.Width  = fields[2];
  _rect.Height = fields[3];
}

bool AnimationList::Animation::operator==(const std::string& name) const
{
  return (_name == name);
}
